<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this</title>
</head>
<body>
<script>

    a = 10;

    console.log(a); // window.a  this.a
    console.log(window.a); // window.a  this.a
    console.log(this.a); // window.a  this.a


    //this => EC 执行上下文
    {// 1.谁调用 this指向谁(.前面是谁 this就指向谁)
        let obj = {
            name: "obj",
            func: function(){
                console.log(this);//obj
            }
        };
        obj.func()
    }
    {//2.当没有人调用的时候this默认指向window
        console.log(this);
        /*window.func = function () {

        };*/
//        window.func();
        function func() {
            console.log(this);//window
        }
        func();
    }
    {// 3. 构造函数中的this, 指向实例本身
        function Person(name) {
            this.name = name;
            this.age = 20;
        }
        Person.prototype.say = function () {
            console.log(this); //person1
            console.log("My name's " + this.name)
        };

        let person1 = new Person("mike");
        let person12 = new Person("mike");
        let person13 = new Person("mike");
        let person14 = new Person("mike");
        person1.say()
    }
    {//4. call apply bind
        let obj = {
            birth: 1990,
            year: 2021,
            age: function (pram1, pram2) {
                console.log(this);//obj
                console.log("这是传入的参数: " + pram1 + " " + pram2);
                console.log("这是计算完成的年龄: " + (this.year - this.birth));
            }
        };
        obj.age(33, 44);
        //call apply bind 强制改变方法中的this指向, 第一个参数是 要改变的this

        /*obj.age.call({
            year: 2021,
            birth: 2000
        }, 666, 888);*/

        /*obj.age.apply({
            year: 2021,
            birth: 2000
        }, [666, 888]);*/

        //bind

        let getAgeFn = obj.age.bind({
            year: 2021,
            birth: 2000
        }, 666, 888);
        getAgeFn()
     /*
        function getDataCallback() {
            console.log(this);
        }

        $.on("getData",getDataCallback.bind(this))
        $.emit("getData",getDataCallback.bind(this))*/

    }

    {//ES5中this指向混乱
        let obj = {
            name: "obj",
            func: function () {
                function fn() {
                    console.log(this)//window    希望this=obj
                }
                fn();
            }
        };
        obj.func()
    }

    {//解决ES5中this指向混乱的方案
        let obj = {
            name: "obj",
            func: function () {
                console.log(this);//obj
                let that = this;
                function fn() {//闭包
                    //this = that;
                    console.log(that)//window    希望this=obj
                }
                fn();
            }
        };
        obj.func()
    }

    {//箭头函数解决方案
        let obj = {
            name: "obj",
            func: function () {
//                this
                let fn = ()=> {
                    console.log(this)//this=obj
                };
                fn();
            }
        };
        obj.func()
    }

    //箭头函数的出现就是为了解决ES5的function中this指向混乱的问题
    //箭头函数没有自己的this,它的this来自上级作用域(父级上下文)
    //箭头函数的this不会在调用的时候被改变, 因为在箭头函数声明的时候他的this就已经被永久的确定了

    let obj = {};
    setTimeout(function () {
        console.log(this);//window
    }, 3000);
    setTimeout(()=>{
        console.log(this);
    }, 3000)




</script>
</body>
</html>